using System;
using System.Collections.Generic;
using System.IO;
using HCore.Unity.Core;
using UnityEngine;

namespace HCore.Tests.Runtime.Tilemap
{
    public class Tilemap
    {
        private readonly Grid2D<TilemapGridObject> mGrid;

        private Action mOnGridObjectLoadListener;

        public Tilemap(int width, int height, float cellSize, Vector2 originPosition)
        {
            mGrid = new Grid2D<TilemapGridObject>(width, height, (grid2D, x, y) => new TilemapGridObject(grid2D, x, y), originPosition, cellSize, true);
        }

        public void SetTilemapSprite(Vector2 worldPosition, TilemapSprite tilemapSprite)
        {
            var tilemapGridObject = mGrid.GetCell(worldPosition);
            tilemapGridObject?.SetTilemapSprite(tilemapSprite);
        }

        public void SetTilemapVisual(TilemapVisual tilemapVisual)
        {
            tilemapVisual.SetupGrid(this, mGrid);
        }

        public void Save(string path)
        {
            var list = new List<TilemapGridObject.SaveObject>(mGrid.Width * mGrid.Height);
            mGrid.Foreach((x, y, gridObject) => list.Add(gridObject.Save()));
            var saveObject = new TilemapSaveObject { TilemapObjectSaveObjectArray = list.ToArray() };

            var jsonBody = JsonUtility.ToJson(saveObject);
            File.WriteAllText(path, jsonBody);
        }

        public void Load(string path)
        {
            if (File.Exists(path))
            {
                var jsonBody = File.ReadAllText(path);
                var tilemapSaveObject = JsonUtility.FromJson<TilemapSaveObject>(jsonBody);
                foreach (var saveObject in tilemapSaveObject.TilemapObjectSaveObjectArray) mGrid.GetCell(saveObject.x, saveObject.y).Load(saveObject);
                mOnGridObjectLoadListener?.Invoke();
            }
            else
            {
                Debug.LogWarning($"{path}：文件不存在！");
            }
        }

        public void AddGridObjectLoadListener(Action action)
        {
            mOnGridObjectLoadListener += action;
        }

        [Serializable]
        public class TilemapSaveObject
        {
            public TilemapGridObject.SaveObject[] TilemapObjectSaveObjectArray;
        }
    }
}